using System;
using System.Collections;
using UnityEngine;
using Yoozoo.UI.YGUI;
using Random = UnityEngine.Random;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

public class SlotMachineMono : MonoBehaviour
{
    public GameObject[] SlotUnit;

    public float MoveSpeed = 10f;

    public float slowMoveSpeed = 2.333f;

    private float currMoveSpeed;

    private float[] ScrollToIndexArray;
    
    private int[] baseScrollToIndexArray;

    private Vector3[] IndexToPositionArray;

    private Vector3[] BaseIndexToPositionArray;

    private bool isAutoStop = false;

    private bool isStopUpdatePos = true;

    private int targetIndex;

    public float turnTime = 2f;

    public float slowTurnTime = 0.345f;

    private int[] indexMap = new int[] { 4, 5, 6, 0, 1, 2, 3 };

    public string baseImgPath = "Assets/ResourcesAssets/UI/GUI/MiniGame/SlotMachine/icon_MiniGames_Slot_";

    private Action playOverCallback;

    private ResLoader ResLoader;

    void Start()
    {
        ScrollToIndexArray = new float[SlotUnit.Length];
        IndexToPositionArray = new Vector3[SlotUnit.Length + 1];
        BaseIndexToPositionArray= new Vector3[SlotUnit.Length + 1];
        baseScrollToIndexArray=new int[SlotUnit.Length];
        
        float spacing = 126f;
        float maxPosition = Mathf.FloorToInt(SlotUnit.Length / 2) * spacing;

        for (int i = 0; i < SlotUnit.Length; i++)
        {
            ScrollToIndexArray[i] = i;
            baseScrollToIndexArray[i] = i;
            IndexToPositionArray[i] = Vector3.up * (maxPosition - i * spacing);
        }

        // 多加一位占着保证最后一个格子能位移到正确的位置上
        IndexToPositionArray[SlotUnit.Length] = Vector3.up * (maxPosition - SlotUnit.Length * spacing);
        Array.Copy(IndexToPositionArray, BaseIndexToPositionArray, SlotUnit.Length + 1);
        ;
    }

    public void PlayEffectByIndex(int index, Action playOverCallback)
    {
        index--; //lua给过来的，索引从1开始，所以要自减
        targetSourceIndex = baseScrollToIndexArray[index];
        isAutoStop = false;
        isStopUpdatePos = false;
        targetIndex = indexMap[index];
        this.playOverCallback = playOverCallback;
        StartCoroutine(SetMoveSpeed());
    }

    private int targetSourceIndex;

    public void PlayHighlightEffect()
    {
        var animComp = SlotUnit[targetSourceIndex].GetComponent<Animation>();
        animComp.Play("ani_slot");
    }

    //随机开始位置
    public void SetRandomStarScrollIndex()
    {
        int SlotUnitLength = SlotUnit.Length;
        int randomIndex = Random.Range(0, SlotUnitLength);
        var tempScrollArray = new int[SlotUnitLength];
        var tempIndexMap = new int[SlotUnitLength];
        Array.Copy(indexMap, tempIndexMap, SlotUnitLength);
        Array.Copy(baseScrollToIndexArray, tempScrollArray, SlotUnitLength);
        
        for (int i = 0; i < SlotUnitLength; i++)
        {
            int targetIndex = i - randomIndex;
            if (targetIndex < 0)
            {
                targetIndex += SlotUnitLength;
            }
        
            indexMap[i] = tempIndexMap[targetIndex];
            ScrollToIndexArray[i] = tempScrollArray[targetIndex];
            baseScrollToIndexArray[i]= tempScrollArray[targetIndex];
            int imgIndex = SlotUnitLength - i - 1;
            YImage image = SlotUnit[imgIndex].GetComponent<YImage>();
            int imgPathIndex = SlotUnitLength - (int)tempScrollArray[targetIndex];
            string imagePath = baseImgPath + imgPathIndex + ".png";
            ResLoader = ResLoader.Alloc();
            ResLoader.Add2Load(imagePath, typeof(Sprite), ((success, assetName, asset) =>
            {
                if (!success)
                {
                    return;
                }
        
                if (assetName != imagePath)
                {
                    return;
                }
        
                image.sprite = asset as Sprite;
            }));
            ResLoader.Load();
        }
    }

    //随机位置
    public void SetMachineToTargetIndex(int randomIndex)
    {
        int SlotUnitLength = SlotUnit.Length;
        int midIndex = (SlotUnitLength+1)/2;
        int reduceIndex =randomIndex - baseScrollToIndexArray[midIndex];
        var tempScrollArray = new int[SlotUnitLength];
        var tempIndexMap = new int[SlotUnitLength];
        Array.Copy(indexMap, tempIndexMap, SlotUnitLength);
        Array.Copy(baseScrollToIndexArray, tempScrollArray, SlotUnitLength);
        for (int i = 0; i < SlotUnit.Length; i++)
        {
            int targetVal =tempScrollArray[i] + reduceIndex;
            if (targetVal >= SlotUnitLength)
            {
                targetVal -= SlotUnitLength;
            }else if (targetVal < 0)
            {
                targetVal += SlotUnitLength;
            }
            indexMap[i] = tempIndexMap[targetVal];
            ScrollToIndexArray[i] = tempScrollArray[targetVal];
            baseScrollToIndexArray[i]= tempScrollArray[targetVal];
            SlotUnit[i].transform.localPosition = IndexToPositionArray[targetVal];
        }
    }

    // 抽奖动画速度控制
    IEnumerator SetMoveSpeed()
    {
        currMoveSpeed = MoveSpeed;
        yield return new WaitForSeconds(turnTime);
        currMoveSpeed = slowMoveSpeed;
        yield return new WaitForSeconds(slowTurnTime);
        // 这里只管移动就行，时间到了之后将自动暂停设置为true，然后update再计算是否移动到了指定的目标位置
        isAutoStop = true;
    }

    void Update()
    {
        if (isStopUpdatePos) return;

        float t = Time.deltaTime * currMoveSpeed;
        // 这步操作用于避免帧率过低时，调用间隔过久，增量时间补偿导致t值过大，跳了多个格子，出现格子位置重叠 中间空缺问题
        if (t > 1)
        {
            t -= Mathf.FloorToInt(t);
        }

        for (int i = 0; i < SlotUnit.Length; i++)
        {
            ScrollToIndexArray[i] += t;
            SlotUnit[i].transform.localPosition = MovePosition(i);
        }
    }

    Vector3 MovePosition(int i)
    {
        int index = Mathf.FloorToInt(ScrollToIndexArray[i]);
        if (index > IndexToPositionArray.Length - 2)
        {
            ScrollToIndexArray[i] -= index;
            if (i == targetIndex && isAutoStop)
            {
                isStopUpdatePos = true;
                this.playOverCallback?.Invoke();
                int targetIndex = (int)ScrollToIndexArray[i];
                return BaseIndexToPositionArray[targetIndex];
            }

            return IndexToPositionArray[0];
        }
        else
        {
            return Vector3.Lerp(IndexToPositionArray[index], IndexToPositionArray[index + 1],
                ScrollToIndexArray[i] - index);
        }
    }
}